﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using TouchRC.MetadataCaching.Extensions;

namespace TouchRC.MetadataCaching
{
    public class MovieSummary : IMediaSummary
    {
        public FileInfo MetadataFile { get; set; }
        public FileInfo Poster { get; set; }
        public FileInfo Backdrop { get; set; }
        public List<FileInfo> AssociatedFiles { get; set; }
        public string Name { get; set; }
        public string Id { get; set; }
        public MediaType MediaType { get { return MediaType.Movie; } }
        public string Description { get; set; }

        public override string ToString()
        {
            return Name;
        }
    }

    public class TvShowSummary : IMediaName
    {
        public string Name { get; set;} 
        public int Id;
        public FileInfo Metadata;
        public FileInfo Poster;
        public FileInfo Backdrop;
        public SeasonCollection Seasons;
        public string Description { get; set; }

        public override string ToString()
        {
            return Name;
        }
    }

    public class SeasonSummary : IMediaName
    {
        public string Name { get; set; }
        public EpisodeCollection Episodes;

        public override string ToString()
        {
            return Name;
        }
    }

    public class EpisodeSummary : IMediaSummary
    {
        public string Name { get; set; }
        public int Id;
        public int EpisodeNumber;
        public FileInfo MetadataFile { get; set; }
        public string TvShowName;
        public string SeasonName;
        public FileInfo AssociatedFile;
        public FileInfo Poster { get; set; }
        public FileInfo Backdrop { get; set; }
        public MediaType MediaType { get { return MediaType.TV; } }
        public string Description { get; set; }

        public override string ToString()
        {
            return string.Format("{0} - {1} - {2} - {3}", TvShowName, SeasonName, EpisodeNumber, Name);
        }
    }

    public class VirtualCache : IMediaName
    {
        public string Name { get; set; }
        public TvShowCollection TvShows;
        public MovieCollection Movies;

        public override string ToString()
        {
            return Name;
        }

        public static explicit operator List<IMediaName>(VirtualCache cache)
        {
            List<IMediaName> media = new List<IMediaName>();
            foreach (MovieSummary movie in cache.Movies)
            {
                IMediaName mediaName = movie;
                media.Add(mediaName);
            }
            foreach (TvShowSummary tvShow in cache.TvShows)
            {
                IMediaName mediaName = tvShow;
                media.Add(mediaName);
            }
            media.Sort((a, b) => a.Name.CompareTo(b.Name));
            return media;
        }
    }

    public class MovieCollection : List<MovieSummary>
    {
        public static implicit operator List<IMediaName>(MovieCollection movieList)
        {
            List<IMediaName> media = new List<IMediaName>();
            foreach (MovieSummary movie in movieList)
            {
                IMediaName mediaName = movie;
                media.Add(mediaName);
            }
            media.Sort((a, b) => a.Name.CompareTo(b.Name));
            return media;
        }
    }

    public class TvShowCollection : List<TvShowSummary>
    {
        public static implicit operator List<IMediaName>(TvShowCollection tvList)
        {
            List<IMediaName> media = new List<IMediaName>();
            foreach (TvShowSummary tvShow in tvList)
            {
                IMediaName mediaName = tvShow;
                media.Add(mediaName);
            }
            media.Sort((a, b) => a.Name.CompareTo(b.Name));
            return media;
        }
    }

    public class SeasonCollection : List<SeasonSummary>
    {
        public static implicit operator List<IMediaName>(SeasonCollection seasonList)
        {
            List<IMediaName> media = new List<IMediaName>();
            foreach (SeasonSummary season in seasonList)
            {
                IMediaName mediaName = season;
                media.Add(mediaName);
            }
            media.Sort((a, b) => a.Name.CompareTo(b.Name));
            return media;
        }
    }

    public class EpisodeCollection : List<EpisodeSummary>
    {
        public static implicit operator List<IMediaName>(EpisodeCollection seasonList)
        {
            List<IMediaName> media = new List<IMediaName>();
            foreach (EpisodeSummary season in seasonList)
            {
                IMediaName mediaName = season;
                media.Add(mediaName);
            }
            media.Sort((a, b) => a.Name.CompareTo(b.Name));
            return media;
        }
    }

    public class MetadataCollection : List<VirtualCache>, IMediaName
    {
        string m_Name = "Media Browser";
        public IMediaSummary QueryFileName(string fileName)
        {
            foreach (VirtualCache cache in this)
            {
                if (cache != null)
                {
                    var movie = from potential in cache.Movies
                                let files = potential.AssociatedFiles
                                from file in files
                                where file.GetFileNameWithoutExtension() == fileName
                                select potential;

                    if (movie.Count() > 0)
                        return movie.First();

                    var tvShow = from potential in cache.TvShows
                                 from potSeason in potential.Seasons
                                 from potEpisode in potSeason.Episodes
                                 where potEpisode.AssociatedFile.GetFileNameWithoutExtension().Equals(fileName)
                                 select new EpisodeSummary
                                 {
                                     AssociatedFile = potEpisode.AssociatedFile,
                                     Backdrop = potential.Backdrop,
                                     Description = potEpisode.Description,
                                     EpisodeNumber = potEpisode.EpisodeNumber,
                                     Id = potEpisode.Id,
                                     MetadataFile = potEpisode.MetadataFile,
                                     Name = potEpisode.Name,
                                     Poster = potential.Poster,
                                     SeasonName = potSeason.Name,
                                     TvShowName = potential.Name
                                 };

                    if (tvShow.Count() > 0)
                        return tvShow.First();
                }
            }
            return null;
        }

        public static implicit operator List<IMediaName>(MetadataCollection cacheList)
        {
            List<IMediaName> media = new List<IMediaName>();
            foreach (VirtualCache cache in cacheList)
            {
                IMediaName mediaName = cache;
                media.Add(mediaName);
            }
            media.Sort((a, b) => a.Name.CompareTo(b.Name));
            return media;
        }

        #region IMediaName Members

        public string Name
        {
            get
            {
                return m_Name;
            }
            set
            {
                m_Name = value;
            }
        }

        #endregion
    }

    public interface IMediaName
    {
        string Name { get; set; }
    }

    public interface IMediaSummary : IMediaName
    {
        FileInfo Poster { get; set; }
        FileInfo Backdrop { get; set; }
        FileInfo MetadataFile { get; set; }
        MediaType MediaType { get; }
        string Description { get; set; }
    }

    public enum MediaType
    {
        TV,
        Movie
    }
}
